<?php

namespace Trawind\Basics\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\DB;

class BatchUnique implements Rule
{

    private $object;
    private $tabelObject;
    private $keyName;
    private $attribute;
    private $batchDatas;
    private $isSelected;
    private $indexList;
    /**
     * Create a new rule instance.
     *
     * Unique constructor.
     * @param $tabelObject
     */
    public function __construct($object, $tabelObject)
    {
        $this->object = $object;
        $this->tabelObject = $tabelObject;
        $this->keyName = $this->tabelObject->getKeyName();
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {

        $data = explode(".", $attribute);
        $firstFiled = array_shift($data);
        $this->attribute = $firstFiled;

        $finalFiled = array_pop($data);
        $allData = $this->object->get($firstFiled);

        $this->getIndexList($allData, $finalFiled);
        if (!$this->isSelected) {
            // get batch attribute
            $hasData = DB::table($this->tabelObject->getTable())
                ->select($this->keyName, $finalFiled)
                ->whereIn($finalFiled, $this->indexList)
                ->get()
                ->toArray();
            $this->batchDatas = (array) array_column($hasData, $this->keyName, $finalFiled);
            $this->isSelected = true;
        }
        if (isset($this->batchDatas[$value])) {
            foreach ($data as $val) {
                $allData = $allData[$val];
            }
            $id = isset($allData[$this->keyName]) ? $allData[$this->keyName] : 0;
            if ($id && $this->batchDatas[$value] == $id) {
                return true;
            }
            return false;
        }
        return true;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return __('validation.unique', ['attribute' => __('validation.attributes.'.$this->attribute)]);
    }

    /**
     * @param $array
     * @param $index
     */
    private function getIndexList($array, $index) {
        if (!is_array($array)) {
            return ;
        }
        foreach ($array as $key => $item) {
            if (is_array($item)) {
                $this->getIndexList($item, $index);
            } else if ($key == $index) {
                $this->indexList[] = $item;
            }
        }
        return ;
    }
}
